<?php
namespace Common\Model;

class UserModel extends \Think\Model
{
	//保存用户请求的参数
	private $requet = array();
	
	//字段映射
	protected $_map = array(
		'loginPass' => 'login_pwd',
		'tradePass' => 'trade_pwd',
		'avatarId' => 'avatar_id',
		'pwdErrCount' =>'pwd_err_count',
		'lockCount' => 'lock_count',
		'lockTime' => 'lock_time',
		'regTime' => 'reg_tiem',
		'regIp' => 'reg_ip',
		'lastLogin' => 'last_login',
		'lastIp' => 'last_ip',
		'recommendId' => 'recommend_id',
		'createTime' => 'create_time',
		'updateTime' => 'update_time',
		'bitStatus' => 'bit_status',
	);
	
	//自动验证
	protected $_validate = array(
		array('id', '/^\d+$/', '参数错误', 1, 'regex', 2),
		array('mobile', '/^1\d{10}$/', '手机号错误', 1, 'regex', 1),
		array('mobile', '', '手机号已被使用', 1, 'unique', 1),
//		array('code', '', '/^\d{4,6}$/', 1, '验证码错误', 'regex', 1),
//		array('code', 'checkCode', '验证码已过期', 1, 'callback', 1),
//		array('login_pwd', '/^\w{32,64}$/', '密码格式错误，请进行加密', 1, 'regex', 1),
//		array('recommendCode', '/^\w{6,12}$/', '推荐码错误', 2),
		
		//10登录验证
		array('username', '/^1\d{10}$/', '手机号不存在', 1, 'regex', 10),
//		array('login_pwd', '/^\w{32,64}$/', '密码格式错误，请进行加密', 1, 'regex', 10),
		//11退出登录验证
		array('userToken', '/^\w{32,64}$/', '请传入正确的user_token', 1, 'regex', 11),
			
			//12解锁
		array('username', '/^[\w\x{4e00}-\x{9fa5}]{2,}$/u', '用户名错误', 1, 'regex', 12),
	);
	
	//自动完成
	protected $_auto = array(
		array('create_time', NOW_TIME, 1, 'string'),
		array('update_time', NOW_TIME, 3, 'string'),
		array('reg_time', NOW_TIME, 1, 'string'),
		array('reg_ip', 'get_client_ip', 1, 'function'),
		array('last_login', NOW_TIME, 3, 'string'),
		array('last_ip', 'get_client_ip', 3, 'function'),
		array('status', 1, 1, 'string')
	);

	/**
	 * 添加用户
	 * @param array $data
	 * @author 刘新
	 */
	public function addUser($param)
	{
		//保存用户请求的参数
		$this->requet = $param;
		
		//创建数据对象是否创建成功
		$data = $this->create($param);
		if(!$data) return array('error' => 1, 'info' => $this->getError());
		
		//生成密用户码盐
		$data['salt'] = $this->salt = hash('md5', \Common\Util\Util::randStr(20, 2).$this->mobile);
		$this->login_pwd = \Common\Util\Util::encrypt($this->login_pwd);
		$result = array('error' => 0, 'info' => array());
		//开启事务
		$this->startTrans();
		
		try {
			//保存用户
			$id = $this->add();
			if(!$id) throw new \Exception('注册失败');
			
			//生成user_token
			$content = \Common\Util\Util::randStr(60, 2) . $data['mobile'] . NOW_TIME . $data['salt'];
			$userToken = \Common\Util\Util::encrypt($content);
			
			//获取user_token有效期
			$expireTime = global_config('user_token_expire');
			$expireTime = time() + ($expireTime ? $expireTime : 30) * 24 * 3600;
			
			//生成user_token数据
			$ut['userId'] = $id;
			$ut['userToken'] = $userToken;
			$ut['expireTime'] = $expireTime;
			$ut['mobile'] = $data['mobile'];
			
			//保存user_token
			$res = D('UserToken')->addUserToken($ut);
			if($res['error'] !== 0) throw new \Exception('user_token添加失败:' . $res['info']);
			
//			//如果有推荐码，则更新
//			if($param['recommendCode']) {
//				//生成邀请码
//				$code = $param['recommendCode'];
//
//					$data = array();
//					$Recommendlist = M('Recommend')->where(array('code'=>$code))->order('recommend_id desc')->find();
//					if(empty($Recommendlist)){
//						throw new \Exception('邀请码不存在');
//					}else{
//						$recommend_id = $Recommendlist['recommend_id'];
//					}
//					$data['code'] = $code;
//					$data['recommended_id'] = $id;
//					$data['recommend_id'] = $recommend_id;
//					$data['create_time'] = time();
//					$data['update_time'] = time();
//					$data['status'] = 1;
//					$rc = D('Recommend')->addRecommend($data);
//
////				$rcData['status'] = 1;
////				$rcData['recommendedId'] = $id;
////				$rcData['code'] = $param['recommendCode'];
////				$rc = D('Recommend')->editRecommend($rcData);
//				if($rc['error'] !== 0) throw new \Exception('推荐人更新状态:' . $rc['info']);
//			}
			
			//添加用户详情信息
			$res = D('UserDetail')->addDetail(array('user_id' => $id));
			if($res['error'] !== 0) throw new \Exception('用户详情添加失败:' . $res['info']);
			
			//生成用户账户信息
			$res = D('Account')->addAcc(array('user_id' => $id));
			if($res['error'] !== 0) throw new \Exception('用户账户添加失败:' . $res['info']);

			//注册成功提交事务
			$info['userId'] = $id;
			$info['userToken'] = $userToken;
			$info['expireTime'] = $expireTime;
			$result['info'] = $info;
			$this->commit();
		} catch(\Exception $e) {
			$this->rollback();
			$result['info'] = $e->getMessage();
			$result['error'] = 1;
		}
		
		return $result;
	}

	/**
	 * 用户登录
	 * @author 刘新
	 */
	public function login($data)
	{
		//创建数据对象
		if(!$this->create($data, 10)) return array('error' => 1, 'info' => $this->getError());

		//构造查询条件
		$where['mobile'] = $data['username'];
		//查询并判断查询结果
		$user = $this->where($where)->find();

		if(!$user) return array('error' => 1, 'info' => '手机号未注册');
		if($user['status'] != 1) return array('error' => 1, 'info' => '用户异常');
		$is_trade = 0;
		if(!empty($user['tradePass'])){
			$is_trade = '1';
		}
		$is_authenticate = $user['authentication']?$user['authentication']:0;

		//密码输入错误有次数限制
		$loginPass = \Common\Util\Util::encrypt($data['loginPass']);

		if($user['loginPass'] !== $loginPass) {
			return $this->pwdError($user['pwdErrCount'] + 1, $user['id'], $user['lockCount'], $user['bitStatus'], $user['mobile']);
		}
		
		//获取用户user_token
		$ut = M('UserToken')->where(array('user_id' => $user['id']))->order('expire_time desc')->field('id,user_token,status')->find();
		if(!$ut) return array('error' => 1, 'info' => 'user_token获取失败');
		if($ut['status'] != 1) return array('error' => 1, 'info' => '用户user_token异常');
		
		//更新user_token有效期
		$expireTime = global_config('user_token_expire');
		$expireTime = time() + ($expireTime ? $expireTime : 30) * 86400;
		$res = M('UserToken')->where('id=' . $ut['id'])->setField('expire_time', $expireTime);
		if(!$res) return array('error' => 1, 'info' => 'user_token更新失败');


		$detail = M('UserDetail')->where(array('user_id' => $user['id']))->field( 'realname,social_no')->find();
		$isdetail = $detail['social_no']?1:0;
		//构造返回数据
		$result['error'] = 0;
		$result['info'] = array('userToken' => $ut['user_token'], 'userId' => $user['id'], 'expireTime' => $expireTime,'is_trade'=>$is_trade,'nickname'=>$user['nickname'],'username'=>$user['mobile'],"sex"=>$user['sex'],"liveAddress"=>$user['liveAddress']);
		
//		//查询用户头像
//		$where = array();
//		$where['u.id'] = $user['id'];
//		$avatar = $this->avatar($where);
//		$result['info']['avatar_url'] = '';
//
//		if($avatar[0]['url']) {
//			$result['info']['avatar_url'] = $avatar[0]['url']!=false?$avatar[0]['url']:'';
//		}
		return $result;
	}
	
	/**
	 * 验证验证码的有效期
	 * @param string $code
	 * @author 刘新
	 */
	public function checkCode($code)
	{
		$mobile = $this->requet['mobile'];
		$res = M('Sms')->where(array('mobile' => $mobile, 'status' => 1))->order('expire_time desc')->field('code,expire_time')->find();
		if(!$res) return false;
		if($code == $res['code'] && $res['expire_time'] > time()) return true;
		return false;
	}
	
	/**
	 * 密码错误
	 * @param string $nowErrCount
	 */
	public function pwdError($nowErrCount, $userId, $lockCount, $bitStatus, $mobile)
	{
//		$maxErrCount = global_config('pwd_err_count');
//
//		if($nowErrCount >= $maxErrCount) {
//			$ec['bit_status'] = $bitStatus | 256;
//			$ec['lock_time'] = NOW_TIME;
//			$ec['lock_count'] = $lockCount + 1;
//			$ec['pwd_err_count'] = $nowErrCount;
//			$ec = $this->where('id=' . $userId)->save($ec);
//
//			//如果锁定成功
//			if($ec) {
//
//				D('UserLog')->addLog(array('mobile' => $mobile, 'content' => '密码错误超过3次，账号锁定','type'=>1));
//				return array('error' => 1, 'info' => '密码错误超过3次，账号已被锁定');
//			}
//
//		} else {
//			$ec = $this->where('id=' . $userId)->setInc('pwd_err_count', 1);
//		}


			
		return array('error' => 1, 'info' => "密码错误");
	}
	
	/**
	 * 用户退出登录
	 * @author 刘新
	 */
	public function logout($data)
	{
		//创建数据对象
		if(!$this->create($data, 11)) return array('error' => 1, 'info' => $this->getError());
		$p['user_token'] = $data['userToken'];
		$res = M('UserToken')->where($p)->save(array('expire_time' => NOW_TIME));
		if(!$res) return array('error' => 1, 'info' => '退出失败');
		return array('error' => 0, 'info' => '退出成功');
	}
	
	/**
	 * 编辑用户
	 * @author 刘新
	 */
	public function editUser($data)
	{
		//创建数据对象
		if(!$this->create($data)) return array('error' => 1, 'info' => $this->getError());
		
		//更新用户信息
		$res = $this->save();
		return $res;		
	}
	
	/**
	 * 查询用户头像
	 * @author 刘新
	 */
	public function avatar($where)
	{
		if($where['f.status'] !== 0 && !$where['f.status']) $where['f.status'] = 1;
		$field = 'u.id,f.name,f.url';
		$avatars = $this->alias('u')->join('join __FILE__ f on u.avatar_id=f.id')->where($where)->field($field)->select();
		return $avatars;
	}
	
	/**
	 * 账号解锁
	 * @author 刘新
	 */
	public function unlock($data)
	{
		//查询用户信息
		$user = $this->find($data['id']);
		if(!$user)  return array('error' => 1, 'info' => '用户不存在或查询失败');
		
		//构造解锁账号数据
		$udata = array('id' => $data['id'], 'pwdErrCount' => 0, 'bitStatus' => $user['bitStatus'] ^ 256);
		
		//开启事务
		$this->startTrans();
		
		try {
			//解锁
			if(!$this->create($udata)) throw new \Exception('数据对象创建失败');
			$res = $this->save();
			if(!$res) throw new \Exception('账号解锁失败');
			
			//日志,构造解锁账号日志数据
			$ldata = array('log_id'=>$data['target_id'], 'admin_id'=>$data['admin_id'], 'admin_name'=>$data['admin_name']);
			$ldata['create_time'] = NOW_TIME;
			$ldata['update_time'] = NOW_TIME;
			$ldata['status'] = 1;
			$ldata['target_id'] = $user['id'];
			$ldata['type'] = C('ADMIN_LOG_TYPE')['UNLOCK'];
			$ldata['content'] = $data['content'];
			$res = M('AdminLog')->add($ldata);
			if(!$res) throw new \Exception('日志添加失败');
			
			//提交事务 
			$this->commit();
			$return = array('error' => 0, 'info' => '解锁成功');
		} catch(\Exception $e) {
			$this->rollback();
			$return = array('error' => 1, 'info' => $e->getMessage());
		}
		
		return $return;
	}

	/**
	 * 重置密码
	 * @author 刘新
	 */
	public function resetPwd($data)
	{
		//查询用户信息
		$user = $this->where(array('id'=>$data['id'], 'status'=>1))->find();
		if(!$user)  return array('error' => 1, 'info' => '用户不存在或查询失败');
	
		//是否进行实名认证
		if(!$user['bitStatus'] & 1) return array('error' => 1, 'info' => '该用户没有进行实名认证，无法重置密码');
		
		//查询用户详情
		$detail = M('UserDetail')->where(array('user_id' => $user['id'], 'status' => 1))->find();
		if(!$detail) return array('error' => 1, 'info' => '用户详情信息查询失败');
		
		//判断用户提供的真实姓名
		if($data['realname'] !== $detail['realname']) return array('error' => 1, 'info' => '真实姓名与实名认证的不一致');
		
		//随机生成密码
		$newPwd = \Common\Util\Util::randStr(6, 1);
		$secure = \Common\Util\Util::encrypt(md5($newPwd));
		
		//发送短信
		$res = \Common\Util\Util::sms($user['mobile'], $newPwd, 2);
		if(!$res) return array('error' => 1, 'info' => '重置密码短信发送失败');

		//开启事务
		$this->startTrans();
	
		try {
			$udata = array('id' => $data['id'], 'loginPass' => $secure);
			if(!$this->create($udata)) throw new \Exception($this->getError());
			$res = $this->save();
			if(!$res) throw new \Exception('重置密码失败');
				
			//日志
			$ldata = array('target_id'=>$user['id'], 'admin_id'=>$data['admin_id'], 'admin_name'=>$data['admin_name']);
			$ldata['create_time'] = NOW_TIME;
			$ldata['update_time'] = NOW_TIME;
			$ldata['status'] = 1;
			$ldata['type'] = C('ADMIN_LOG_TYPE')['RESET_PWD'];
			$ldata['content'] = $data['content'];
			$res = M('AdminLog')->add($ldata);
			if(!$res) throw new \Exception('日志添加失败');
				
			//提交事务
			$this->commit();
			$return = array('error' => 0, 'info' => '操作成功');
		} catch(\Exception $e) {
			$this->rollback();
			$return = array('error' => 1, 'info' => $e->getMessage());
		}
	
		return $return;
	}
	
	/**
	 * 查询用户收益信息
	 * @author 刘新
	 */
	public function profit($userId)
	{
		
	}
	
	/**
	 * 查询用户 头像
	 * @param array $data
	 */
	public function userAvatar(&$data)
	{
		// 获取用户ID列表
		$userIds = array();
		foreach($data as &$d) {
			$userIds[] = $d['user_id'];
			$q['avatar_id'] = '';
			$q['avatar_url'] = '';
			$q['mobile'] = '';
		}
			
		// 查询用户头像
		$avatars = $this->where(array('id'=>array('in', $userIds)))->field('id,avatar_id,avatar_url,mobile')->select();

		if($avatars) {
			foreach($data as &$d) {
				foreach($avatars  as $ava) {
					if($ava['id'] === $d['user_id']) {
						$d['mobile'] = substr_replace($ava['mobile'], '****', 3, 4);
						$d['avatar_id'] = $ava['avatar_id'];
						$d['avatar_url'] = $ava['avatar_url'];
						break;
					}
				}
			}
		}
		return $data;
	}
}